#![allow(dead_code)]
use std::path::Path;

use bc_db::{BaseBcDb, DBError};

pub enum MiscItemDbKey {
    LatestBlockIdInBestChain,
    BestHeight,
    TimeBestReceived,
    PotentialBlocksOfMainChain,
}

impl std::fmt::Display for MiscItemDbKey {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            MiscItemDbKey::LatestBlockIdInBestChain => write!(f, "latest_block_id_in_best_chain"),
            MiscItemDbKey::BestHeight => write!(f, "best_height"),
            MiscItemDbKey::TimeBestReceived => write!(f, "time_best_received"),
            MiscItemDbKey::PotentialBlocksOfMainChain => {
                write!(f, "potential_blocks_of_main_chain")
            }
        }
    }
}

#[derive(Debug)]
pub(crate) struct MiscItemStorageBase {
    misc_db: BaseBcDb,
}

impl MiscItemStorageBase {
    pub(crate) fn new(db_root_dir: &Path) -> Result<Self, DBError> {
        let path = crate::get_misc_item_db_path(db_root_dir);
        Ok(Self {
            misc_db: BaseBcDb::new(&path)?,
        })
    }

    // insert or update
    pub(crate) async fn put(&self, key: MiscItemDbKey, value: Vec<u8>) -> Result<(), DBError> {
        let k = Self::convert_key(key);
        self.misc_db.put(&k, value).await?;
        Ok(())
    }
    pub(crate) async fn get(&self, key: MiscItemDbKey) -> Result<Option<Vec<u8>>, DBError> {
        let k = Self::convert_key(key);
        let t = self.misc_db.get(&k).await?;
        if let Some(value) = t {
            Ok(Some(value))
        } else {
            Ok(None)
        }
    }
    pub(crate) async fn erase(&self, key: MiscItemDbKey) -> Result<(), DBError> {
        let k = Self::convert_key(key);
        self.misc_db.erase(&k).await?;
        Ok(())
    }

    pub(crate) async fn exists(&self, key: MiscItemDbKey) -> bool {
        let k = Self::convert_key(key);
        self.misc_db.exists(&k).await
    }

    pub(crate) async fn flush_database(&self) -> Result<(), DBError> {
        self.misc_db.flush().await?;
        Ok(())
    }

    fn convert_key(key: MiscItemDbKey) -> String {
        key.to_string()
    }
}
